// DBX2.05 :: Docking Boxes (dbx)
// *****************************************************
// DOM scripting by brothercake -- http://www.brothercake.com/
// GNU Lesser General Public License -- http://www.gnu.org/licenses/lgpl.html
//******************************************************
var dbx;
function dbxManager(sid) {
    dbx = this;
    if (!/^[-_a-z0-9]+$/i.test(sid)) {
        alert('Error from dbxManager:\n"' + sid + '" is an invalid session ID');
        return;
    }
    this.supported = !(document.getElementsByTagName('*').length == 0 || (navigator.vendor == 'KDE' && typeof window.sidebar == 'undefined'));
    if (!this.supported) {
        return;
    }
    this.etype = typeof document.addEventListener != 'undefined' ? 'addEventListener' : typeof document.attachEvent != 'undefined' ? 'attachEvent' : 'none';
    this.eprefix = (this.etype == 'attachEvent' ? 'on' : '');
    if (typeof window.opera != 'undefined' && parseFloat(navigator.userAgent.toLowerCase().split(/opera[\/ ]/)[1].split(' ')[0], 10) < 7.5) {
        this.etype = 'none';
    }
    if (this.etype == 'none') {
        this.supported = false;
        return;
    }
    this.running = 0;
    this.sid = sid;
    this.savedata = {};
    this.cookiestate = this.getCookieState();
}
dbxManager.prototype.setCookieState = function () {
    var now = new Date();
    now.setTime(now.getTime() + (365 * 24 * 60 * 60 * 1000));
    var str = '';
    for (j in this.savedata) {
        if (typeof this.savedata[j] != 'function') {
            str += j + '=' + this.savedata[j] + '&'
        }
    }
    this.state = str.replace(/^(.+)&$/, '$1');
    this.cookiestring = this.state.replace(/,/g, '|');
    this.cookiestring = this.cookiestring.replace(/=/g, ':');
    if (typeof this.onstatechange == 'undefined' || this.onstatechange()) {
        document.cookie = 'dbx-' + this.sid + '=' + this.cookiestring + '; expires=' + now.toGMTString() + '; path=/';
    }
};
dbxManager.prototype.getCookieState = function () {
    this.cookiestate = null;
    if (document.cookie) {
        if (document.cookie.indexOf('dbx-' + this.sid) != -1) {
            this.cookie = document.cookie.split('dbx-' + this.sid + '=')[1].split(';')[0].split('&');
            for (var i in this.cookie) {
                if (typeof this.cookie[i] != 'function') {
                    this.cookie[i] = this.cookie[i].replace(/\|/g, ',');
                    this.cookie[i] = this.cookie[i].replace(/:/g, '=');
                    this.cookie[i] = this.cookie[i].split('=');
                    this.cookie[i][1] = this.cookie[i][1].split(',');
                }
            }
            this.cookiestate = {};
            for (i in this.cookie) {
                if (typeof this.cookie[i] != 'function') {
                    this.cookiestate[this.cookie[i][0]] = this.cookie[i][1];
                }
            }
        }
    }
    return this.cookiestate;
};
dbxManager.prototype.addDataMember = function (gid, order) {
    this.savedata[gid] = order;
};
dbxManager.prototype.createElement = function (tag) {
    return typeof document.createElementNS != 'undefined' ? document.createElementNS('http://www.w3.org/1999/xhtml', tag) : document.createElement(tag);
};
dbxManager.prototype.getTarget = function (e, pattern, node) {
    if (typeof node != 'undefined') {
        var target = node;
    } else {
        target = typeof e.target != 'undefined' ? e.target : e.srcElement;
    }
    var regex = new RegExp(pattern, '');
    while (!regex.test(target.className)) {
        target = target.parentNode;
    }
    return target;
};
function dbxGroup(gid, dir, thresh, fix, ani, togs, def, open, close, move, toggle, kmove, ktoggle, syntax) {
    if (!/^[-_a-z0-9]+$/i.test(gid)) {
        alert('Error from dbxGroup:\n"' + gid + '" is an invalid container ID');
        return;
    }
    this.container = document.getElementById(gid);
    if (this.container == null || !dbx.supported) {
        return;
    }
    var self = this;
    this.gid = gid;
    this.dragok = false;
    this.box = null;
    this.vertical = dir == 'vertical';
    this.threshold = parseInt(thresh, 10);
    this.restrict = fix == 'yes';
    this.resolution = parseInt(ani, 10);
    this.toggles = togs == 'yes';
    this.defopen = def != 'closed';
    this.vocab = {
        'open': open,
        'close': close,
        'move': move,
        'toggle': toggle,
        'kmove': kmove,
        'ktoggle': ktoggle,
        'syntax': syntax
    };
    this.container.style.position = 'relative';
    this.container.style.display = 'block';
    if (typeof window.opera != 'undefined') {
        this.container.style.display = 'run-in';
    }
    this.boxes = [];
    this.buttons = [];
    this.order = [];
    this.eles = this.container.getElementsByTagName('*');
    for (var i = 0; i < this.eles.length; i++) {
        if (/dbx\-box/i.test(this.eles[i].className) && !/dbx\-dummy/i.test(this.eles[i].className)) {
            this.eles[i].style.position = 'relative';
            this.eles[i].style.display = 'block';
            this.boxes.push(this.eles[i]);
            this.eles[i].className += ' dbx-box-open';
            this.eles[i].className += ' dbxid' + this.order.length;
            this.order.push(this.order.length.toString() + '+');
            this.eles[i][dbx.etype](dbx.eprefix + 'mousedown', function (e) {
                if (!e) {
                    e = window.event;
                }
                self.mousedown(e, dbx.getTarget(e, 'dbx\-box'));
            }, false);
        }
        if (/dbx\-handle/i.test(this.eles[i].className)) {
            this.eles[i].style.position = 'relative';
            this.eles[i].style.display = 'block';
            this.eles[i].className += ' dbx-handle-cursor';
            this.eles[i].setAttribute('title', this.eles[i].getAttribute('title') == null || this.eles[i].title == '' ? this.vocab.move : this.vocab.syntax.replace('%mytitle%', this.eles[i].title).replace('%dbxtitle%', this.vocab.move));
            if (this.toggles) {
                this.buttons.push(this.addToggleBehavior(this.eles[i]));
            } else {
                this.eles[i][dbx.etype](dbx.eprefix + 'key' + (typeof document.uniqueID != 'undefined' || navigator.vendor == 'Apple Computer, Inc.' ? 'down' : 'press'), function (e) {
                    if (!e) {
                        e = window.event;
                    }
                    return self.keypress(e, dbx.getTarget(e, 'dbx\-handle'));
                }, false);
                this.eles[i][dbx.etype](dbx.eprefix + 'focus', function (e) {
                    if (!e) {
                        e = window.event;
                    }
                    self.createTooltip(null, dbx.getTarget(e, 'dbx\-handle'));
                }, false);
                this.eles[i][dbx.etype](dbx.eprefix + 'blur', function () {
                    self.removeTooltip();
                }, false);
            }
        }
    }
    dbx.addDataMember(this.gid, this.order.join(','));
    var dummy = this.container.appendChild(dbx.createElement('span'));
    dummy.className = 'dbx-box dbx-dummy';
    dummy.style.display = 'block';
    dummy.style.width = '0';
    dummy.style.height = '0';
    dummy.style.overflow = 'hidden';
    if (this.vertical) {
        dummy.className += ' dbx-offdummy';
    }
    this.boxes.push(dummy);
    if (dbx.cookiestate != null && typeof dbx.cookiestate[this.gid] != 'undefined') {
        var num = dbx.cookiestate[this.gid].length;
        if (num == this.boxes.length - 1) {
            for (i = 0; i < num; i++) {
                var index = parseInt(dbx.cookiestate[this.gid][i], 10);
                this.container.insertBefore(this.boxes[index], dummy);
                if (this.toggles && /\-$/.test(dbx.cookiestate[this.gid][i])) {
                    this.toggleBoxState(this.buttons[index], false);
                }
            }
            this.getBoxOrder();
        }
    } else if (!this.defopen && this.toggles) {
        var len = this.buttons.length;
        for (i = 0; i < len; i++) {
            this.toggleBoxState(this.buttons[i], true);
        }
    }
    document[dbx.etype](dbx.eprefix + 'mouseout', function (e) {
        if (typeof e.target == 'undefined') {
            e = window.event;
            e.relatedTarget = e.toElement;
        }
        if (e.relatedTarget == null) {
            self.mouseup(e);
        }
    }, false);
    document[dbx.etype](dbx.eprefix + 'mousemove', function (e) {
        self.mousemove(e);
        return !self.dragok;
    }, false);
    document[dbx.etype](dbx.eprefix + 'mouseup', function (e) {
        self.mouseup(e);
    }, false);
    this.keydown = false;
    document[dbx.etype](dbx.eprefix + 'keydown', function () {
        self.keydown = true;
    }, false);
    document[dbx.etype](dbx.eprefix + 'keyup', function () {
        self.keydown = false;
    }, false);
}
dbxGroup.prototype.addToggleBehavior = function () {
    var self = this;
    var button = arguments[0].appendChild(dbx.createElement('a'));
    button.appendChild(document.createTextNode('\u00a0'));
    button.style.cursor = 'pointer';
    button.href = 'javascript:void(null)';
    button.className = 'dbx-toggle dbx-toggle-open';
    button.setAttribute('title', this.vocab.toggle.replace('%toggle%', this.vocab.close));
    button.hasfocus = typeof window.opera != 'undefined' || navigator.vendor == 'Apple Computer, Inc.' ? null : false;
    this.tooltip = null;
    button.onclick = function () {
        if (this.hasfocus === true || this.hasfocus === null) {
            self.removeTooltip();
            self.toggleBoxState(this, true);
        }
    };
    button['onkey' + (typeof document.uniqueID != 'undefined' || navigator.vendor == 'Apple Computer, Inc.' ? 'down' : 'press')] = function (e) {
        if (!e) {
            e = window.event;
        }
        return self.keypress(e, this);
    };
    button.onfocus = function () {
        var len = self.buttons.length;
        for (var i = 0; i < len; i++) {
            self.buttons[i].className = self.buttons[i].className.replace(/[ ](dbx\-toggle\-hilite\-)(open|closed)/, '');
        }
        var isopen = (/dbx\-toggle\-open/.test(this.className));
        this.className += ' dbx-toggle-hilite-' + (isopen ? 'open' : 'closed');
        self.createTooltip(isopen, this);
        this.isactive = true;
        if (this.hasfocus !== null) {
            this.hasfocus = true;
        }
    };
    button.onblur = function () {
        this.className = this.className.replace(/[ ](dbx\-toggle\-hilite\-)(open|closed)/, '');
        self.removeTooltip();
        if (this.hasfocus !== null) {
            this.hasfocus = false;
        }
    };
    return button;
};
dbxGroup.prototype.toggleBoxState = function (button, regen) {
    var isopen = (/dbx\-toggle\-open/.test(button.className));
    var parent = dbx.getTarget(null, 'dbx\-box', button);
    dbx.box = parent;
    dbx.toggle = button;
    if (typeof dbx.container == 'undefined') {
        dbx.group = dbx.getTarget(null, 'dbx\-group', parent);
    } else {
        dbx.group = dbx.container;
    }
    if ((!isopen && (typeof dbx.onboxopen == 'undefined' || dbx.onboxopen())) || (isopen && (typeof dbx.onboxclose == 'undefined' || dbx.onboxclose()))) {
        button.className = 'dbx-toggle dbx-toggle-' + (isopen ? 'closed' : 'open');
        button.title = this.vocab.toggle.replace('%toggle%', isopen ? this.vocab.open : this.vocab.close);
        if (typeof button.isactive != 'undefined') {
            button.className += ' dbx-toggle-hilite-' + (isopen ? 'closed' : 'open')
        }
        parent.className = parent.className.replace(/[ ](dbx-box-)(open|closed)/, ' $1' + (isopen ? 'closed' : 'open'));
        if (regen) {
            this.getBoxOrder();
        }
    }
};
dbxGroup.prototype.shiftBoxPosition = function (e, anchor, positive) {
    var parent = dbx.getTarget(null, 'dbx\-box', anchor);
    dbx.group = this.container;
    dbx.box = parent;
    dbx.event = e;
    if (typeof dbx.onboxdrag == 'undefined' || dbx.onboxdrag()) {
        var positions = [];
        var len = this.boxes.length;
        for (var i = 0; i < len; i++) {
            positions[i] = [i, this.boxes[i][this.vertical ? 'offsetTop' : 'offsetLeft']];
            if (parent == this.boxes[i]) {
                this.idref = i;
            }
        }
        positions.sort(this.compare);
        for (i = 0; i < len; i++) {
            if (positions[i][0] == this.idref) {
                if ((positive && i < len - 2) || (!positive && i > 0)) {
                    var sibling = this.boxes[positions[i + (positive ? 1 : -1)][0]];
                    if (this.resolution > 0) {
                        var visipos = {'x': parent.offsetLeft, 'y': parent.offsetTop};
                        var siblingpos = {'x': sibling.offsetLeft, 'y': sibling.offsetTop};
                    }
                    var obj = {'insert': (positive ? sibling : parent), 'before': (positive ? parent : sibling)};
                    this.container.insertBefore(obj.insert, obj.before);
                    if (this.resolution > 0) {
                        var animators = {
                            'sibling': new dbxAnimator(this, sibling, siblingpos, this.resolution, true, anchor),
                            'parent': new dbxAnimator(this, parent, visipos, this.resolution, true, anchor)
                        };
                    } else {
                        anchor.focus();
                    }
                    break;
                }
            }
        }
        this.getBoxOrder();
    }
};
dbxGroup.prototype.compare = function (a, b) {
    return a[1] - b[1];
};
dbxGroup.prototype.createTooltip = function (isopen, anchor) {
    if (this.keydown) {
        this.tooltip = this.container.appendChild(dbx.createElement('span'));
        this.tooltip.style.visibility = 'hidden';
        this.tooltip.className = 'dbx-tooltip';
        if (isopen != null) {
            this.tooltip.appendChild(document.createTextNode(this.vocab.kmove + this.vocab.ktoggle.replace('%toggle%', isopen ? this.vocab.close : this.vocab.open)));
        } else {
            this.tooltip.appendChild(document.createTextNode(this.vocab.kmove));
        }
        var parent = dbx.getTarget(null, 'dbx\-box', anchor);
        this.tooltip.style.left = parent.offsetLeft + 'px';
        this.tooltip.style.top = parent.offsetTop + 'px';
        var tooltip = this.tooltip;
        window.setTimeout(function () {
            if (tooltip != null) {
                tooltip.style.visibility = 'visible';
            }
        }, 500);
    }
};
dbxGroup.prototype.removeTooltip = function () {
    if (this.tooltip != null) {
        this.tooltip.parentNode.removeChild(this.tooltip);
        this.tooltip = null;
    }
};
dbxGroup.prototype.mousedown = function (e, box) {
    var node = typeof e.target != 'undefined' ? e.target : e.srcElement;
    if (node.nodeName == '#text') {
        node = node.parentNode;
    }
    if (!/dbx\-(toggle|box|group)/i.test(node.className)) {
        while (!/dbx\-(handle|box|group)/i.test(node.className)) {
            node = node.parentNode;
        }
    }
    if (/dbx\-handle/i.test(node.className)) {
        this.removeTooltip();
        this.released = false;
        this.initial = {'x': e.clientX, 'y': e.clientY};
        this.current = {'x': 0, 'y': 0};
        this.createCloneBox(box);
        if (typeof e.preventDefault != 'undefined') {
            e.preventDefault();
        }
        if (typeof document.onselectstart != 'undefined') {
            document.onselectstart = function () {
                return false;
            }
        }
    }
};
dbxGroup.prototype.mousemove = function (e) {
    if (this.dragok && this.box != null) {
        this.positive = this.vertical ? (e.clientY > this.current.y ? true : false) : (e.clientX > this.current.x ? true : false);
        this.current = {'x': e.clientX, 'y': e.clientY};
        var overall = {'x': this.current.x - this.initial.x, 'y': this.current.y - this.initial.y};
        if (((overall.x >= 0 && overall.x <= this.threshold) || (overall.x <= 0 && overall.x >= 0 - this.threshold)) && ((overall.y >= 0 && overall.y <= this.threshold) || (overall.y <= 0 && overall.y >= 0 - this.threshold))) {
            this.current.x -= overall.x;
            this.current.y -= overall.y;
        }
        if (this.released || overall.x > this.threshold || overall.x < (0 - this.threshold) || overall.y > this.threshold || overall.y < (0 - this.threshold)) {
            dbx.group = this.container;
            dbx.box = this.box;
            dbx.event = e;
            if (typeof dbx.onboxdrag == 'undefined' || dbx.onboxdrag()) {
                this.released = true;
                if (!this.restrict || !this.vertical) {
                    this.boxclone.style.left = (this.current.x - this.difference.x) + 'px';
                }
                if (!this.restrict || this.vertical) {
                    this.boxclone.style.top = (this.current.y - this.difference.y) + 'px';
                }
                this.moveOriginalToPosition(this.current.x, this.current.y);
                if (typeof e.preventDefault != 'undefined') {
                    e.preventDefault();
                }
            }
        }
    }
    return true;
};
dbxGroup.prototype.mouseup = function (e) {
    if (this.box != null) {
        this.moveOriginalToPosition(e.clientX, e.clientY);
        this.removeCloneBox();
        this.getBoxOrder();
        if (typeof document.onselectstart != 'undefined') {
            document.onselectstart = function () {
                return true;
            }
        }
    }
    this.dragok = false;
};
dbxGroup.prototype.keypress = function (e, anchor) {
    if (/^(3[7-9])|(40)$/.test(e.keyCode)) {
        this.removeTooltip();
        if ((this.vertical && /^(38|40)$/.test(e.keyCode)) || (!this.vertical && /^(37|39)$/.test(e.keyCode))) {
            this.shiftBoxPosition(e, anchor, /^[3][78]$/.test(e.keyCode) ? false : true);
            if (typeof e.preventDefault != 'undefined') {
                e.preventDefault();
            } else {
                return false;
            }
            typeof e.stopPropagation != 'undefined' ? e.stopPropagation() : e.cancelBubble = true;
            this.keydown = false;
        }
    }
    return true;
};
dbxGroup.prototype.getBoxOrder = function () {
    this.order = [];
    var len = this.eles.length;
    for (var j = 0; j < len; j++) {
        if (/dbx\-box/i.test(this.eles[j].className) && !/dbx\-(clone|dummy)/i.test(this.eles[j].className)) {
            this.order.push(this.eles[j].className.split('dbxid')[1] + (/dbx\-box\-open/i.test(this.eles[j].className) ? '+' : '-'));
        }
    }
    dbx.savedata[this.gid] = this.order.join(',');
    dbx.setCookieState();
};
dbxGroup.prototype.createClone = function () {
    var clone = this.container.appendChild(arguments[0].cloneNode(true));
    clone.className += ' dbx-clone';
    clone.style.position = 'absolute';
    clone.style.visibility = 'hidden';
    clone.style.zIndex = arguments[1];
    clone.style.left = arguments[2].x + 'px';
    clone.style.top = arguments[2].y + 'px';
    clone.style.width = arguments[0].offsetWidth + 'px';
    clone.style.height = arguments[0].offsetHeight + 'px';
    return clone;
};
dbxGroup.prototype.createCloneBox = function (box) {
    this.box = box;
    this.position = {'x': this.box.offsetLeft, 'y': this.box.offsetTop};
    this.difference = {'x': (this.initial.x - this.position.x), 'y': (this.initial.y - this.position.y)};
    this.boxclone = this.createClone(this.box, 30000, this.position);
    this.boxclone.style.cursor = 'move';
    this.dragok = true;
};
dbxGroup.prototype.removeCloneBox = function () {
    this.container.removeChild(this.boxclone);
    this.box.style.visibility = 'visible';
    this.box = null;
};
dbxGroup.prototype.moveOriginalToPosition = function (clientX, clientY) {
    var cloneprops = {
        'xy': this.vertical ? clientY - this.difference.y : clientX - this.difference.x,
        'wh': this.vertical ? this.boxclone.offsetHeight : this.boxclone.offsetWidth
    };
    this.box.style.visibility = 'hidden';
    this.boxclone.style.visibility = 'visible';
    var len = this.boxes.length;
    for (var i = 0; i < len; i++) {
        var boxprops = {
            'xy': this.vertical ? this.boxes[i].offsetTop : this.boxes[i].offsetLeft,
            'wh': this.vertical ? this.boxes[i].offsetHeight : this.boxes[i].offsetWidth
        };
        if ((this.positive && cloneprops.xy + cloneprops.wh > boxprops.xy && cloneprops.xy < boxprops.xy) || (!this.positive && cloneprops.xy < boxprops.xy && cloneprops.xy + cloneprops.wh > boxprops.xy)) {
            if (this.boxes[i] == this.box) {
                return;
            }
            var sibling = this.box.nextSibling;
            while (sibling.className == null || !/dbx\-box/.test(sibling.className)) {
                sibling = sibling.nextSibling;
            }
            if (this.boxes[i] == sibling) {
                return;
            }
            if (this.resolution > 0) {
                if (this.box[this.vertical ? 'offsetTop' : 'offsetLeft'] < boxprops.xy) {
                    var visibox = this.boxes[i].previousSibling;
                    while (visibox.className == null || !/dbx\-box/.test(visibox.className)) {
                        visibox = visibox.previousSibling;
                    }
                } else {
                    visibox = this.boxes[i];
                }
                var visipos = {'x': visibox.offsetLeft, 'y': visibox.offsetTop};
            }
            var prepos = {'x': this.box.offsetLeft, 'y': this.box.offsetTop};
            this.container.insertBefore(this.box, this.boxes[i]);
            this.initial.x += (this.box.offsetLeft - prepos.x);
            this.initial.y += (this.box.offsetTop - prepos.y);
            if (this.resolution > 0 && visibox != this.box) {
                var animator = new dbxAnimator(this, visibox, visipos, this.resolution, false, null);
            } else {
            }
            break;
        }
    }
};
function dbxAnimator(caller, box, pos, res, kbd, anchor) {
    this.caller = caller;
    this.box = box;
    this.timer = null;
    var before = pos[this.caller.vertical ? 'y' : 'x'];
    var after = this.box[this.caller.vertical ? 'offsetTop' : 'offsetLeft'];
    if (before != after) {
        if (dbx.running > this.caller.boxes.length - 1) {
            return;
        }
        var clone = this.caller.createClone(this.box, 29999, arguments[2]);
        clone.style.visibility = 'visible';
        this.box.style.visibility = 'hidden';
        this.animateClone(clone, before, after > before ? after - before : 0 - (before - after), this.caller.vertical ? 'top' : 'left', res, kbd, anchor);
    }
}
dbxAnimator.prototype.animateClone = function (clone, current, change, dir, res, kbd, anchor) {
    var self = this;
    var count = 0;
    dbx.running++;
    this.timer = window.setInterval(function () {
        count++;
        current += change / res;
        clone.style[dir] = current + 'px';
        if (count == res) {
            window.clearTimeout(self.timer);
            self.timer = null;
            dbx.running--;
            self.caller.container.removeChild(clone);
            self.box.style.visibility = 'visible';
            if (kbd) {
                if (anchor != null && anchor.parentNode.style.visibility != 'hidden') {
                    anchor.focus();
                } else if (self.caller.toggles) {
                    var button = self.caller.buttons[parseInt(self.box.className.split('dbxid')[1], 10)];
                    if (button != null && typeof button.isactive != 'undefined') {
                        button.focus();
                    }
                }
            }
        }
    }, 20);
};
if (typeof window.attachEvent != 'undefined') {
    window.attachEvent('onunload', function () {
        var ev = ['mousedown', 'mousemove', 'mouseup', 'mouseout', 'click', 'keydown', 'keyup', 'focus', 'blur', 'selectstart', 'statechange', 'boxdrag', 'boxopen', 'boxclose'];
        var el = ev.length;
        var dl = document.all.length;
        for (var i = 0; i < dl; i++) {
            for (var j = 0; j < el; j++) {
                document.all[i]['on' + ev[j]] = null;
            }
        }
    });
}